package com.novel2comic.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.novel2comic.service.DashscopeService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.util.*;

@RestController
@RequestMapping("/api")
public class ApiController {
	private final ObjectMapper mapper = new ObjectMapper();
	private final DashscopeService dashscopeService;
	public ApiController(DashscopeService dashscopeService) { this.dashscopeService = dashscopeService; }
	@Value("${novel2comic.mock:true}")
	private boolean mock;
	@Value("${novel2comic.dashscopeApiKey:}")
	private String apiKey;

	@GetMapping("/health")
	public Map<String, Object> health() {
		return Map.of("ok", true, "mock", mock, "dashscope", apiKey != null && !apiKey.isBlank());
	}

	@PostMapping(value = "/analyze", consumes = MediaType.APPLICATION_JSON_VALUE)
	public Map<String, Object> analyze(@RequestBody Map<String, Object> body) throws Exception {
		int target = ((Number) body.getOrDefault("targetPanelCount", 12)).intValue();
		Object text = body.getOrDefault("text", "");
		Map<String, Object> real = dashscopeService.analyzeToPanels(String.valueOf(text), target);
		if (real != null) {
			// 尝试解析 LLM 返回 JSON 字符串
			Object raw = real.get("raw");
			try {
				Map data = mapper.readValue(String.valueOf(raw), Map.class);
				return Map.of("ok", true, "data", data, "mock", false);
			} catch (Exception ignore) { /* 回退示例 */ }
		}
		Map<String, Object> data = sampleAnalysis(target);
		return Map.of("ok", true, "data", data, "mock", true);
	}

	@PostMapping(value = "/generate", consumes = MediaType.APPLICATION_JSON_VALUE)
	public Map<String, Object> generate(@RequestBody Map<String, Object> body) throws Exception {
		List<Map<String, Object>> panels = (List<Map<String, Object>>) body.getOrDefault("panels", List.of());
		String style = String.valueOf(body.getOrDefault("stylePreset", "日式漫画"));
		List<Map<String, String>> urls = dashscopeService.generateImages(panels, style);
		if (urls == null || urls.isEmpty()) {
			List<Map<String, String>> images = new ArrayList<>();
			for (int i = 0; i < panels.size(); i++) {
				Map<String, Object> p = panels.get(i);
				String id = String.valueOf(p.getOrDefault("id", "p" + (i + 1)));
				images.add(Map.of("panelId", id, "url", placeholderImage(id)));
			}
			return Map.of("ok", true, "data", Map.of("images", images), "mock", true);
		}
		return Map.of("ok", true, "data", Map.of("images", urls), "mock", false);
	}

	private Map<String, Object> sampleAnalysis(int target) {
		List<Map<String, Object>> panels = new ArrayList<>();
		panels.add(panel("p1", List.of(12, 13), "medium", "eye_level", "校门口黄昏",
				List.of(charObj("林一", "紧张", "小跑")), List.of(dialog("林一", "要迟到了！"))));
		panels.add(panel("p2", List.of(14), "close", "low", "校门口",
				List.of(charObj("林一", "着急", null)), List.of(dialog("林一", "快点！"))));
		panels.add(panel("p3", List.of(15, 16), "long", "high", "宿舍走廊",
				List.of(), List.of()));
		return Map.of("panels", panels, "global", Map.of("targetPanelCount", target));
	}

	private Map<String, Object> panel(String id, List<Integer> src, String shot, String angle, String setting,
				List<Map<String, Object>> chars, List<Map<String, Object>> dialogs) {
		return Map.of(
				"id", id,
				"sourceParagraphIds", src,
				"shot", shot,
				"angle", angle,
				"setting", setting,
				"characters", chars,
				"dialog", dialogs
		);
	}

	private Map<String, Object> charObj(String name, String emotion, String action) {
		Map<String, Object> m = new HashMap<>();
		m.put("name", name);
		m.put("emotion", emotion);
		if (action != null) m.put("action", action);
		return m;
	}

	private Map<String, Object> dialog(String speaker, String text) {
		return Map.of("speaker", speaker, "text", text);
	}

	private String placeholderImage(String label) {
		String svg = "<svg xmlns='http://www.w3.org/2000/svg' width='768' height='1024'>" +
				"<defs><linearGradient id='g' x1='0' x2='1'><stop offset='0%' stop-color='#7c3aed'/><stop offset='100%' stop-color='#22d3ee'/></linearGradient></defs>" +
				"<rect width='100%' height='100%' fill='url(#g)'/>" +
				"<text x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-family='sans-serif' font-size='48' fill='white'>" + label + "</text>" +
				"</svg>";
		return "data:image/svg+xml;utf8," + java.net.URLEncoder.encode(svg, StandardCharsets.UTF_8);
	}
}
